/**************************************************************************
 *                                                                        *
 *         Copyright (c) 2014 by Generalplus Inc.                         *
 *                                                                        *
 *  This software is copyrighted by and is the property of Generalplus    *
 *  Inc. All rights are reserved by Generalplus Inc.                      *
 *  This software may only be used in accordance with the                 *
 *  corresponding license agreement. Any unauthorized use, duplication,   *
 *  distribution, or disclosure of this software is expressly forbidden.  *
 *                                                                        *
 *  This Copyright notice MUST not be removed or modified without prior   *
 *  written consent of Generalplus Technology Co., Ltd.                   *
 *                                                                        *
 *  Generalplus Inc. reserves the right to modify this software           *
 *  without notice.                                                       *
 *                                                                        *
 *  Generalplus Inc.                                                      *
 *  No.19, Industry E. Rd. IV, Hsinchu Science Park                       *
 *  Hsinchu City 30078, Taiwan, R.O.C.                                    *
 *                                                                        *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "drv_l1_sfr.h"
#include "drv_l1_mipi.h"
#include "drv_l1_i2c.h"
#include "drv_l2_sensor.h"
#include "drv_l2_sccb.h"
#include "drv_l2_cdsp.h"
#include "drv_l2_cdsp_config.h"
#include "gplib_print_string.h"

#if (defined _SENSOR_GC1034_CDSP_MIPI) && (_SENSOR_GC1034_CDSP_MIPI == 1)

#include "drv_l2_user_calibration.h"

/**************************************************************************
 *                           C O N S T A N T S                            *
 **************************************************************************/
#ifndef DISABLE
#define DISABLE 0
#endif
#ifndef ENABLE
#define ENABLE	1
#endif


#define AEAWB_TASK_ONOFF	ENABLE
#define MIPI_ISR_TEST				0
#define MIPI_LANE_NO				MIPI_1_LANE // 1 or 2 lane
#if (MIPI_LANE_NO == MIPI_2_LANE)
#define MIPI_DEV_NO 				0				//2Lane only selcet MIPI_0
#else
#define MIPI_DEV_NO					0				//1Lane can 0:MIPI_0 or 1:MIPI_1
#endif

#define GC1034_ID					0x42

/*MIPI Rx Input & ISP Input*/
#define GC1034_WIDTH				1280
#define GC1034_HEIGHT				720

/*ISP Output*/
#define GC1034_OUT_WIDTH			1280
#define GC1034_OUT_HEIGHT			720


#define GC1034_25FPS_50HZ_DAY_EV_IDX		120
#define GC1034_25FPS_50HZ_NIGHT_EV_IDX		160
#define GC1034_25FPS_50HZ_EXP_TIME_TOTAL	(235+2)
#define GC1034_25FPS_50HZ_INIT_EV_IDX		((GC1034_25FPS_50HZ_DAY_EV_IDX + GC1034_25FPS_50HZ_NIGHT_EV_IDX) >> 1)
#define GC1034_25FPS_50HZ_MAX_EV_IDX		(GC1034_25FPS_50HZ_EXP_TIME_TOTAL - 10)

#define GC1034_25FPS_60HZ_DAY_EV_IDX		96
#define GC1034_25FPS_60HZ_NIGHT_EV_IDX		149
#define GC1034_25FPS_60HZ_EXP_TIME_TOTAL	(227+4)
#define GC1034_25FPS_60HZ_INIT_EV_IDX		((GC1034_25FPS_60HZ_DAY_EV_IDX + GC1034_25FPS_60HZ_NIGHT_EV_IDX) >> 1)
#define GC1034_25FPS_60HZ_MAX_EV_IDX		(GC1034_25FPS_60HZ_EXP_TIME_TOTAL - 10)


/**************************************************************************
 *                              M A C R O S                               *
 **************************************************************************/

/**************************************************************************
 *                          D A T A    T Y P E S                          *
 **************************************************************************/
/*
typedef struct regval8_s
{
	INT8U	reg_num;
	INT8U	value;
} regval8_t;
*/

/**************************************************************************
 *                         G L O B A L    D A T A                         *
 **************************************************************************/

static int						*p_expTime_table;
static sensor_exposure_t		seInfo;
static int						pre_sensor_a_gain, pre_sensor_time;
static INT32U					gc1034_analog_gain = 0x100;

#if C_SENSOR_SAVE_RAW_DATA
extern INT32U g_raw_mode_idx;
#endif

#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_SW

sccb_config_t	gc1034_handle =
{
	SENSOR_I2C_SCL,		//scl_port
	SENSOR_I2C_DRIVING,	//scl_drv
	SENSOR_I2C_SDA,		//sda_port
	SENSOR_I2C_DRIVING,	//sda_drv
	0,					//pwdn_port
	0,					//pwdn_drv
	0,					//have_pwdn
	8,					//RegBits
	8,					//DataBits
	GC1034_ID,			//slaveAddr
	0x20000,			//timeout
	200					//clock_rate
};

#elif SENSOR_I2C_MODE == SENSOR_I2C_MODE_HW
static INT8U 					read_i2c = 0;

static drv_l1_i2c_bus_handle_t	gc1034_handle =
{
	SENSOR_I2C_DEV,
	GC1034_ID,
	100
};
#endif

static mipi_config_t gc1034_mipi_cfg =
{
	DISABLE,			/* low power, 0:disable, 1:enable */

#if MIPI_LANE_NO == MIPI_1_LANE

	D_PHY_SAMPLE_POS,	/* byte clock edge, 0:posedge, 1:negedge */
	MIPI_1_LANE,		/* lane */
	D_PHY_BYTE_CLK,		/* byte clock source */
#elif MIPI_LANE_NO == MIPI_2_LANE
	D_PHY_SAMPLE_POS,
	MIPI_2_LANE,		/* lane */
	GENERATE_PIXEL_CLK, /* byte clock source */
#endif
	MIPI_AUTO_DETECT,	/* data mode, 0:auto detect, 1:user define */
	MIPI_RAW10,			/* data type, valid when data mode is 1*/
	MIPI_DATA_TO_CSI,	/* data type, 1:data[7:0]+2':00 to cdsp, 0: 2'00+data[7:0] to csi */
	0,					//NULL,			/* RSD 2 */
	GC1034_WIDTH,		/* width, 0~0xFFFF */
	GC1034_HEIGHT,		/* height, 0~0xFFFF */
#if SENSOR_FLIP
	2,
	6,
#else
	2,					/* back porch, 0~0xF *///If Set 4 have show paper color at left side.u2.20160119
	6,
#endif
	ENABLE,				/* blanking_line_en, 0:disable, 1:enable */
	0,					//NULL,			/* RSD 3 */
	ENABLE,				/* ecc, 0:disable, 1:enable */
	MIPI_ECC_ORDER3,	/* ecc order */

	150,//250,/* data mask, unit is ns */ /*250 for 48Mhz, 1400 for 40Mhz*/

	MIPI_CHECK_HS_SEQ	//MIPI_CHECK_LP_00	/* check hs sequence or LP00 for clock lane */
};

static const regval8_t	gc1034_reset_table[] =
{ // SYS
	{ 0xFE, 0x80 },

	{ 0xFF, 0xFF }
 };

static const regval8_t	gc1034_init_table[] =
{

	//MCLK=24Mhz,MIPI_clock=312MHz
	//HD=1725,VD=750,PCLK=39MHZ,row_time=45.54us
	/////////////////////////////////////////////////////
	//////////////////////   SYS   //////////////////////
	/////////////////////////////////////////////////////
	{0xf2,0x00},
	{0xf6,0x00},
	{0xfc,0x04},
	{0xf7,0x01},
	{0xf8,0x0c},
	{0xf9,0x06},
	{0xfa,0x80},
	{0xfc,0x0e},
	/////////////////////////////////////////////////
	////////////   ANALOG & CISCTL   ////////////////
	/////////////////////////////////////////////////
	{0xfe,0x00},
	{0x03,0x02},
	{0x04,0xa6},
	{0x05,0x02}, //HB
	{0x06,0x07},
	{0x07,0x00}, //VB
	{0x08,0xa0}, //25fps
	//{0x08,0x0a}, //30fps

	{0x09,0x00},
	{0x0a,0x00}, //row start
	{0x0b,0x00},
	{0x0c,0x00}, //col start

	{0x0d,0x02},
	{0x0e,0xf0}, //height 752
	{0x0f,0x05},
	{0x10,0x18}, //width 1304

#if SENSOR_FLIP
	{0x17, 0xc3}, // [0]mirror [1]flip
#else
	{0x17, 0xc0}, // [0]mirror [1]flip
#endif
	{0x18,0x02},
	{0x19,0x08},
	{0x1a,0x18},
	{0x1e,0x50},
	{0x1f,0x80},
	{0x21,0x30},
	{0x23,0xf8},
	{0x25,0x10},
	{0x28,0x20},
	{0x34,0x08}, //data low
	{0x3c,0x10},
	{0x3d,0x0e},
	{0xcc,0x8e},
	{0xcd,0x9a},
	{0xcf,0x70},
	{0xd0,0xab},
	{0xd1,0xc5},
	{0xd2,0xed}, //data high
	{0xd8,0x3c}, //dacin offset
	{0xd9,0x7a},
	{0xda,0x12},
	{0xdb,0x50},
	{0xde,0x0c},
	{0xe3,0x60},
	{0xe4,0x78},
	{0xfe,0x01},
	{0xe3,0x01},
	{0xe6,0x10}, //ramps offset
	/////////////////////////////////////////////////
	//////////////////   ISP   //////////////////////
	/////////////////////////////////////////////////
	{0xfe,0x01},
	{0x80,0x50},
	{0x88,0x73},
	{0x89,0x03},
	{0x90,0x01},
#if SENSOR_FLIP
	{0x92, 0x18}, //crop y offset  //crop win 2<=y<=4
	{0x94, 0x10},//crop y offset  //crop win 2<=x<=5
#else
	{0x92, 0x03}, //3//crop y offset
	{0x94, 0x04},
#endif
	{0x95, 0x02},
	{0x96, 0xD8}, //728
	{0x97, 0x05},
	{0x98, 0x10}, //1296
	/////////////////////////////////////////////////
	//////////////////   BLK   //////////////////////
	/////////////////////////////////////////////////
	{0xfe,0x01},
	{0x40,0x22},
	{0x43,0x03},
	{0x4e,0x3c},
	{0x4f,0x00},
	{0x60,0x00},
	{0x61,0x80},
	/////////////////////////////////////////////////
	//////////////////   GAIN   /////////////////////
	/////////////////////////////////////////////////
	{0xfe,0x01},
	{0xb0,0x48},
	{0xb1,0x01},
	{0xb2,0x00},
	{0xb6,0x00},
	{0xfe,0x02},
	{0x01,0x00},
	{0x02,0x01},
	{0x03,0x02},
	{0x04,0x03},
	{0x05,0x04},
	{0x06,0x05},
	{0x07,0x06},
	{0x08,0x0e},
	{0x09,0x16},
	{0x0a,0x1e},
	{0x0b,0x36},
	{0x0c,0x3e},
	{0x0d,0x56},
	{0xfe,0x02},
	{0xb0,0x00}, //col_gain[11:8]
	{0xb1,0x00},
	{0xb2,0x00},
	{0xb3,0x11},
	{0xb4,0x22},
	{0xb5,0x54},
	{0xb6,0xb8},
	{0xb7,0x60},
	{0xb9,0x00}, //col_gain[12]
	{0xba,0xc0},
	{0xc0,0x20}, //col_gain[7:0]
	{0xc1,0x2d},
	{0xc2,0x40},
	{0xc3,0x5b},
	{0xc4,0x80},
	{0xc5,0xb5},
	{0xc6,0x00},
	{0xc7,0x6a},
	{0xc8,0x00},
	{0xc9,0xd4},
	{0xca,0x00},
	{0xcb,0xa8},
	{0xcc,0x00},
	{0xcd,0x50},
	{0xce,0x00},
	{0xcf,0xa1},
	/////////////////////////////////////////////////
	////////////////   DARKSUN   ////////////////////
	/////////////////////////////////////////////////
	{0xfe,0x02},
	{0x54,0xf7},
	{0x55,0xf0},
	{0x56,0x00},
	{0x57,0x00},
	{0x58,0x00},
	{0x5a,0x04},
	/////////////////////////////////////////////////
	///////////////////   DD   //////////////////////
	/////////////////////////////////////////////////
	{0xfe,0x04},
	{0x81,0x8a},
	/////////////////////////////////////////////////
	//////////////////	 MIPI	/////////////////////
	/////////////////////////////////////////////////
	{0xfe,0x03},
	{0x01,0x03},
	{0x02,0x11},
	{0x03,0x90},
#if 0//(SENSOR_INTERFACE == MIPI_RAW8)	//RAW8
	{0x10, 0x94},
	{0x11, 0x2b},
	{0x12, 0x10}, //RAW8 buffer[7:0] 1296*1=1296
	{0x13, 0x05}, //RAW8 buffer[15:8]
#else	//RAW10
	{0x10, 0x90},
	{0x11, 0x2b},
	{0x12, 0x54}, //RAW10 buffer[7:0] 1288=0x64a
	{0x13, 0x06}, //RAW10 buffer[15:8]
#endif
	{0x15,0x06},
	{0x21,0x02},
	{0x22,0x02},
	{0x23,0x08},
	{0x24,0x02},
	{0x25,0x10},
	{0x26,0x04},
	{0x29,0x02},
	{0x2a,0x02},
	{0x2b,0x04},
	{0xfe,0x00},

	{0xff,0xff}
};

static const int GC1034_mipi_25fps_exp_time_gain_50Hz[GC1034_25FPS_50HZ_EXP_TIME_TOTAL][3] =
{
{8	, (int)(1.00*100), (int)(1.00*64)},
{9	, (int)(1.00*100), (int)(1.00*64)},
{9	, (int)(1.00*100), (int)(1.00*64)},
{9	, (int)(1.00*100), (int)(1.00*64)},
{10	, (int)(1.00*100), (int)(1.00*64)},
{10	, (int)(1.00*100), (int)(1.00*64)},
{10	, (int)(1.00*100), (int)(1.00*64)},
{11	, (int)(1.00*100), (int)(1.00*64)},
{11	, (int)(1.00*100), (int)(1.00*64)},
{11	, (int)(1.00*100), (int)(1.00*64)},
{12	, (int)(1.00*100), (int)(1.00*64)},
{12	, (int)(1.00*100), (int)(1.00*64)},
{13	, (int)(1.00*100), (int)(1.00*64)},
{13	, (int)(1.00*100), (int)(1.00*64)},
{14	, (int)(1.00*100), (int)(1.00*64)},
{14	, (int)(1.00*100), (int)(1.00*64)},
{15	, (int)(1.00*100), (int)(1.00*64)},
{15	, (int)(1.00*100), (int)(1.00*64)},
{16	, (int)(1.00*100), (int)(1.00*64)},
{16	, (int)(1.00*100), (int)(1.00*64)},
{17	, (int)(1.00*100), (int)(1.00*64)},
{17	, (int)(1.00*100), (int)(1.00*64)},
{18	, (int)(1.00*100), (int)(1.00*64)},
{19	, (int)(1.00*100), (int)(1.00*64)},
{19	, (int)(1.00*100), (int)(1.00*64)},
{20	, (int)(1.00*100), (int)(1.00*64)},
{21	, (int)(1.00*100), (int)(1.00*64)},
{21	, (int)(1.00*100), (int)(1.00*64)},
{22	, (int)(1.00*100), (int)(1.00*64)},
{23	, (int)(1.00*100), (int)(1.00*64)},
{24	, (int)(1.00*100), (int)(1.00*64)},
{25	, (int)(1.00*100), (int)(1.00*64)},
{25	, (int)(1.00*100), (int)(1.00*64)},
{26	, (int)(1.00*100), (int)(1.00*64)},
{27	, (int)(1.00*100), (int)(1.00*64)},
{28	, (int)(1.00*100), (int)(1.00*64)},
{29	, (int)(1.00*100), (int)(1.00*64)},
{30	, (int)(1.00*100), (int)(1.00*64)},
{31	, (int)(1.00*100), (int)(1.00*64)},
{32	, (int)(1.00*100), (int)(1.00*64)},
{34	, (int)(1.00*100), (int)(1.00*64)},
{35	, (int)(1.00*100), (int)(1.00*64)},
{36	, (int)(1.00*100), (int)(1.00*64)},
{37	, (int)(1.00*100), (int)(1.00*64)},
{39	, (int)(1.00*100), (int)(1.00*64)},
{40	, (int)(1.00*100), (int)(1.00*64)},
{41	, (int)(1.00*100), (int)(1.00*64)},
{43	, (int)(1.00*100), (int)(1.00*64)},
{44	, (int)(1.00*100), (int)(1.00*64)},
{46	, (int)(1.00*100), (int)(1.00*64)},
{48	, (int)(1.00*100), (int)(1.00*64)},
{49	, (int)(1.00*100), (int)(1.00*64)},
{51	, (int)(1.00*100), (int)(1.00*64)},
{53	, (int)(1.00*100), (int)(1.00*64)},
{55	, (int)(1.00*100), (int)(1.00*64)},
{57	, (int)(1.00*100), (int)(1.00*64)},
{58	, (int)(1.00*100), (int)(1.00*64)},
{61	, (int)(1.00*100), (int)(1.00*64)},
{63	, (int)(1.00*100), (int)(1.00*64)},
{65	, (int)(1.00*100), (int)(1.00*64)},
{67	, (int)(1.00*100), (int)(1.00*64)},
{70	, (int)(1.00*100), (int)(1.00*64)},
{72	, (int)(1.00*100), (int)(1.00*64)},
{75	, (int)(1.00*100), (int)(1.00*64)},
{77	, (int)(1.00*100), (int)(1.00*64)},
{80	, (int)(1.00*100), (int)(1.00*64)},
{83	, (int)(1.00*100), (int)(1.00*64)},
{86	, (int)(1.00*100), (int)(1.00*64)},
{89	, (int)(1.00*100), (int)(1.00*64)},
{92	, (int)(1.00*100), (int)(1.00*64)},
{95	, (int)(1.00*100), (int)(1.00*64)},
{98	, (int)(1.00*100), (int)(1.00*64)},
{102,	(int)(1.00*100), (int)(1.00*64)},
{105,	(int)(1.00*100), (int)(1.00*64)},
{109,	(int)(1.00*100), (int)(1.00*64)},
{113,	(int)(1.00*100), (int)(1.00*64)},
{117,	(int)(1.00*100), (int)(1.00*64)},
{121,	(int)(1.00*100), (int)(1.00*64)},
{125,	(int)(1.00*100), (int)(1.00*64)},
{130,	(int)(1.00*100), (int)(1.00*64)},
{134,	(int)(1.00*100), (int)(1.00*64)},
{139,	(int)(1.00*100), (int)(1.00*64)},
{144,	(int)(1.00*100), (int)(1.00*64)},
{149,	(int)(1.00*100), (int)(1.00*64)},
{154,	(int)(1.00*100), (int)(1.00*64)},
{160,	(int)(1.00*100), (int)(1.00*64)},
{165,	(int)(1.00*100), (int)(1.00*64)},
{171,	(int)(1.00*100), (int)(1.00*64)},
{177,	(int)(1.00*100), (int)(1.00*64)},
{184,	(int)(1.00*100), (int)(1.00*64)},
{190,	(int)(1.00*100), (int)(1.00*64)},
{197,	(int)(1.00*100), (int)(1.00*64)},
{204,	(int)(1.00*100), (int)(1.00*64)},
{211,	(int)(1.00*100), (int)(1.00*64)},
{218,	(int)(1.00*100), (int)(1.00*64)},
{226,	(int)(1.00*100), (int)(1.00*64)},
{226,	(int)(1.04*100), (int)(1.00*64)},
{226,	(int)(1.06*100), (int)(1.00*64)},
{226,	(int)(1.11*100), (int)(1.00*64)},
{226,	(int)(1.15*100), (int)(1.00*64)},
{226,	(int)(1.19*100), (int)(1.00*64)},
{226,	(int)(1.23*100), (int)(1.00*64)},
{226,	(int)(1.27*100), (int)(1.00*64)},
{226,	(int)(1.31*100), (int)(1.00*64)},
{226,	(int)(1.37*100), (int)(1.00*64)},
{226,	(int)(1.41*100), (int)(1.00*64)},
{226,	(int)(1.46*100), (int)(1.00*64)},
{226,	(int)(1.52*100), (int)(1.00*64)},
{226,	(int)(1.57*100), (int)(1.00*64)},
{226,	(int)(1.62*100), (int)(1.00*64)},
{226,	(int)(1.68*100), (int)(1.00*64)},
{226,	(int)(1.74*100), (int)(1.00*64)},
{226,	(int)(1.80*100), (int)(1.00*64)},
{226,	(int)(1.87*100), (int)(1.00*64)},
{226,	(int)(1.93*100), (int)(1.00*64)},
{452,	(int)(1.00*100), (int)(1.00*64)},
{452,	(int)(1.04*100), (int)(1.00*64)},
{452,	(int)(1.06*100), (int)(1.00*64)},
{452,	(int)(1.11*100), (int)(1.00*64)},
{452,	(int)(1.15*100), (int)(1.00*64)},
{452,	(int)(1.19*100), (int)(1.00*64)},
{452,	(int)(1.23*100), (int)(1.00*64)},
{452,	(int)(1.27*100), (int)(1.00*64)},
{452,	(int)(1.31*100), (int)(1.00*64)},
{452,	(int)(1.37*100), (int)(1.00*64)},
{452,	(int)(1.41*100), (int)(1.00*64)},
{452,	(int)(1.46*100), (int)(1.00*64)},
{452,	(int)(1.52*100), (int)(1.00*64)},
{452,	(int)(1.57*100), (int)(1.00*64)},
{452,	(int)(1.62*100), (int)(1.00*64)},
{452,	(int)(1.68*100), (int)(1.00*64)},
{452,	(int)(1.74*100), (int)(1.00*64)},
{452,	(int)(1.80*100), (int)(1.00*64)},
{452,	(int)(1.87*100), (int)(1.00*64)},
{452,	(int)(1.93*100), (int)(1.00*64)},
{678,	(int)(1.31*100), (int)(1.00*64)},
{678,	(int)(1.37*100), (int)(1.00*64)},
{678,	(int)(1.41*100), (int)(1.00*64)},
{678,	(int)(1.46*100), (int)(1.00*64)},
{678,	(int)(1.52*100), (int)(1.00*64)},
{678,	(int)(1.57*100), (int)(1.00*64)},
{678,	(int)(1.62*100), (int)(1.00*64)},
{678,	(int)(1.68*100), (int)(1.00*64)},
{678,	(int)(1.74*100), (int)(1.00*64)},
{678,	(int)(1.80*100), (int)(1.00*64)},
{678,	(int)(1.87*100), (int)(1.00*64)},
{678,	(int)(1.93*100), (int)(1.00*64)},
{904,	(int)(1.52*100), (int)(1.00*64)},
{904,	(int)(1.57*100), (int)(1.00*64)},
{904,	(int)(1.62*100), (int)(1.00*64)},
{904,	(int)(1.68*100), (int)(1.00*64)},
{904,	(int)(1.74*100), (int)(1.00*64)},
{904,	(int)(1.80*100), (int)(1.00*64)},
{904,	(int)(1.87*100), (int)(1.00*64)},
{904,	(int)(1.93*100), (int)(1.00*64)},
{904,	(int)(2.00*100), (int)(1.00*64)},
{904,	(int)(2.07*100), (int)(1.00*64)},
{904,	(int)(2.14*100), (int)(1.00*64)},
{904,	(int)(2.22*100), (int)(1.00*64)},
{904,	(int)(2.30*100), (int)(1.00*64)},
{904,	(int)(2.38*100), (int)(1.00*64)},
{904,	(int)(2.46*100), (int)(1.00*64)},
{904,	(int)(2.55*100), (int)(1.00*64)},
{904,	(int)(2.64*100), (int)(1.00*64)},
{904,	(int)(2.73*100), (int)(1.00*64)},
{904,	(int)(2.83*100), (int)(1.00*64)},
{904,	(int)(2.93*100), (int)(1.00*64)},
{904,	(int)(3.03*100), (int)(1.00*64)},
{904,	(int)(3.14*100), (int)(1.00*64)},
{904,	(int)(3.25*100), (int)(1.00*64)},
{904,	(int)(3.36*100), (int)(1.00*64)},
{904,	(int)(3.48*100), (int)(1.00*64)},
{904,	(int)(3.61*100), (int)(1.00*64)},
{904,	(int)(3.73*100), (int)(1.00*64)},
{904,	(int)(3.86*100), (int)(1.00*64)},
{904,	(int)(4.00*100), (int)(1.00*64)},
{904,	(int)(4.14*100), (int)(1.00*64)},
{904,	(int)(4.29*100), (int)(1.00*64)},
{904,	(int)(4.44*100), (int)(1.00*64)},
{904,	(int)(4.59*100), (int)(1.00*64)},
{904,	(int)(4.76*100), (int)(1.00*64)},
{904,	(int)(4.92*100), (int)(1.00*64)},
{904,	(int)(5.10*100), (int)(1.00*64)},
{904,	(int)(5.28*100), (int)(1.00*64)},
{904,	(int)(5.46*100), (int)(1.00*64)},
{904,	(int)(5.66*100), (int)(1.00*64)},
{904,	(int)(5.86*100), (int)(1.00*64)},
{904,	(int)(6.06*100), (int)(1.00*64)},
{904,	(int)(6.28*100), (int)(1.00*64)},
{904,	(int)(6.50*100), (int)(1.00*64)},
{904,	(int)(6.73*100), (int)(1.00*64)},
{904,	(int)(6.96*100), (int)(1.00*64)},
{904,	(int)(7.21*100), (int)(1.00*64)},
{904,	(int)(7.46*100), (int)(1.00*64)},
{904,	(int)(7.73*100), (int)(1.00*64)},
{904,	(int)(8.00*100), (int)(1.00*64)},
{904,	(int)(8.28*100), (int)(1.00*64)},
{904,	(int)(8.57*100), (int)(1.00*64)},
{904,	(int)(8.88*100), (int)(1.00*64)},
{904,	(int)(9.19*100), (int)(1.00*64)},
{904,	(int)(9.51*100), (int)(1.00*64)},
{904,	(int)(9.85*100), (int)(1.00*64)},
{904,	(int)(10.20*100),(int)(1.00*64)},
{904,	(int)(10.56*100),(int)(1.00*64)},
{904,	(int)(10.93*100),(int)(1.00*64)},
{904,	(int)(11.31*100),(int)(1.00*64)},
{904,	(int)(11.71*100),(int)(1.00*64)},
{904,	(int)(12.13*100),(int)(1.00*64)},
{904,	(int)(12.55*100),(int)(1.00*64)},
{904,	(int)(13.00*100),(int)(1.00*64)},
{904,	(int)(13.45*100),(int)(1.00*64)},
{904,	(int)(13.93*100),(int)(1.00*64)},
{904,	(int)(14.42*100),(int)(1.00*64)},
{904,	(int)(14.93*100),(int)(1.00*64)},
{904,	(int)(15.45*100),(int)(1.00*64)},
{904,	(int)(16.00*100),(int)(1.00*64)},
{904,	(int)(16.56*100),(int)(1.00*64)},
{904,	(int)(17.15*100),(int)(1.00*64)},
{904,	(int)(17.75*100),(int)(1.00*64)},
{904,	(int)(18.38*100),(int)(1.00*64)},
{904,	(int)(19.03*100),(int)(1.00*64)},
{904,	(int)(19.70*100),(int)(1.00*64)},
{904,	(int)(20.39*100),(int)(1.00*64)},
{904,	(int)(21.11*100),(int)(1.00*64)},
{904,	(int)(21.86*100),(int)(1.00*64)},
{904,	(int)(22.63*100),(int)(1.00*64)},
{904,	(int)(23.43*100),(int)(1.00*64)},
{904,	(int)(24.25*100),(int)(1.00*64)},
{904,	(int)(25.11*100),(int)(1.00*64)},
{904,	(int)(25.99*100),(int)(1.00*64)},
{904,	(int)(26.91*100),(int)(1.00*64)},
{904,	(int)(27.86*100),(int)(1.00*64)},
{904,	(int)(28.84*100),(int)(1.00*64)},
{904,	(int)(29.86*100),(int)(1.00*64)},
{904,	(int)(30.91*100),(int)(1.00*64)},
{904, (int)(32.00*100),(int)(1.00*64)},
{904, (int)(33.13*100),(int)(1.00*64)},


};

static const int GC1034_mipi_25fps_exp_time_gain_60Hz[GC1034_25FPS_60HZ_EXP_TIME_TOTAL][3] =
{						// {time, analog gain, digital gain}
{7  , (int)(1.00 *100), (int)(1.00*64)},
{7  , (int)(1.00 *100), (int)(1.00*64)},
{7  , (int)(1.00 *100), (int)(1.00*64)},
{7  , (int)(1.00 *100), (int)(1.00*64)},
{8  , (int)(1.00 *100), (int)(1.00*64)},
{8  , (int)(1.00 *100), (int)(1.00*64)},
{8  , (int)(1.00 *100), (int)(1.00*64)},
{9  , (int)(1.00 *100), (int)(1.00*64)},
{9  , (int)(1.00 *100), (int)(1.00*64)},
{9  , (int)(1.00 *100), (int)(1.00*64)},
{10	, (int)(1.00 *100), (int)(1.00*64)},
{10	, (int)(1.00 *100), (int)(1.00*64)},
{10	, (int)(1.00 *100), (int)(1.00*64)},
{11	, (int)(1.00 *100), (int)(1.00*64)},
{11	, (int)(1.00 *100), (int)(1.00*64)},
{11	, (int)(1.00 *100), (int)(1.00*64)},
{12	, (int)(1.00 *100), (int)(1.00*64)},
{12	, (int)(1.00 *100), (int)(1.00*64)},
{13	, (int)(1.00 *100), (int)(1.00*64)},
{13	, (int)(1.00 *100), (int)(1.00*64)},
{13	, (int)(1.00 *100), (int)(1.00*64)},
{14	, (int)(1.00 *100), (int)(1.00*64)},
{14	, (int)(1.00 *100), (int)(1.00*64)},
{15	, (int)(1.00 *100), (int)(1.00*64)},
{16	, (int)(1.00 *100), (int)(1.00*64)},
{16	, (int)(1.00 *100), (int)(1.00*64)},
{17	, (int)(1.00 *100), (int)(1.00*64)},
{17	, (int)(1.00 *100), (int)(1.00*64)},
{18	, (int)(1.00 *100), (int)(1.00*64)},
{18	, (int)(1.00 *100), (int)(1.00*64)},
{19	, (int)(1.00 *100), (int)(1.00*64)},
{20	, (int)(1.00 *100), (int)(1.00*64)},
{20	, (int)(1.00 *100), (int)(1.00*64)},
{21	, (int)(1.00 *100), (int)(1.00*64)},
{22	, (int)(1.00 *100), (int)(1.00*64)},
{23	, (int)(1.00 *100), (int)(1.00*64)},
{24	, (int)(1.00 *100), (int)(1.00*64)},
{24	, (int)(1.00 *100), (int)(1.00*64)},
{25	, (int)(1.00 *100), (int)(1.00*64)},
{26	, (int)(1.00 *100), (int)(1.00*64)},
{27	, (int)(1.00 *100), (int)(1.00*64)},
{28	, (int)(1.00 *100), (int)(1.00*64)},
{29	, (int)(1.00 *100), (int)(1.00*64)},
{30	, (int)(1.00 *100), (int)(1.00*64)},
{31	, (int)(1.00 *100), (int)(1.00*64)},
{32	, (int)(1.00 *100), (int)(1.00*64)},
{33	, (int)(1.00 *100), (int)(1.00*64)},
{34	, (int)(1.00 *100), (int)(1.00*64)},
{36	, (int)(1.00 *100), (int)(1.00*64)},
{37	, (int)(1.00 *100), (int)(1.00*64)},
{38	, (int)(1.00 *100), (int)(1.00*64)},
{40	, (int)(1.00 *100), (int)(1.00*64)},
{41	, (int)(1.00 *100), (int)(1.00*64)},
{42	, (int)(1.00 *100), (int)(1.00*64)},
{44	, (int)(1.00 *100), (int)(1.00*64)},
{45	, (int)(1.00 *100), (int)(1.00*64)},
{47	, (int)(1.00 *100), (int)(1.00*64)},
{49	, (int)(1.00 *100), (int)(1.00*64)},
{50	, (int)(1.00 *100), (int)(1.00*64)},
{52	, (int)(1.00 *100), (int)(1.00*64)},
{54	, (int)(1.00 *100), (int)(1.00*64)},
{56	, (int)(1.00 *100), (int)(1.00*64)},
{58	, (int)(1.00 *100), (int)(1.00*64)},
{60	, (int)(1.00 *100), (int)(1.00*64)},
{62	, (int)(1.00 *100), (int)(1.00*64)},
{64	, (int)(1.00 *100), (int)(1.00*64)},
{66	, (int)(1.00 *100), (int)(1.00*64)},
{69	, (int)(1.00 *100), (int)(1.00*64)},
{71	, (int)(1.00 *100), (int)(1.00*64)},
{74	, (int)(1.00 *100), (int)(1.00*64)},
{76	, (int)(1.00 *100), (int)(1.00*64)},
{79	, (int)(1.00 *100), (int)(1.00*64)},
{82	, (int)(1.00 *100), (int)(1.00*64)},
{85	, (int)(1.00 *100), (int)(1.00*64)},
{88	, (int)(1.00 *100), (int)(1.00*64)},
{91	, (int)(1.00 *100), (int)(1.00*64)},
{94	, (int)(1.00 *100), (int)(1.00*64)},
{97	, (int)(1.00 *100), (int)(1.00*64)},
{101, (int)(1.00 *100), (int)(1.00*64)},
{104, (int)(1.00 *100), (int)(1.00*64)},
{108, (int)(1.00 *100), (int)(1.00*64)},
{112, (int)(1.00 *100), (int)(1.00*64)},
{116, (int)(1.00 *100), (int)(1.00*64)},
{120, (int)(1.00 *100), (int)(1.00*64)},
{124, (int)(1.00 *100), (int)(1.00*64)},
{128, (int)(1.00 *100), (int)(1.00*64)},
{133, (int)(1.00 *100), (int)(1.00*64)},
{138, (int)(1.00 *100), (int)(1.00*64)},
{142, (int)(1.00 *100), (int)(1.00*64)},
{148, (int)(1.00 *100), (int)(1.00*64)},
{153, (int)(1.00 *100), (int)(1.00*64)},
{158, (int)(1.00 *100), (int)(1.00*64)},
{164, (int)(1.00 *100), (int)(1.00*64)},
{169, (int)(1.00 *100), (int)(1.00*64)},
{175, (int)(1.00 *100), (int)(1.00*64)},
{182, (int)(1.00 *100), (int)(1.00*64)},
{188, (int)(1.00 *100), (int)(1.00*64)},
{188, (int)(1.03 *100), (int)(1.00*64)},
{188, (int)(1.07 *100), (int)(1.00*64)},
{188, (int)(1.10 *100), (int)(1.00*64)},
{188, (int)(1.14 *100), (int)(1.00*64)},
{188, (int)(1.19 *100), (int)(1.00*64)},
{188, (int)(1.23 *100), (int)(1.00*64)},
{188, (int)(1.28 *100), (int)(1.00*64)},
{188, (int)(1.33 *100), (int)(1.00*64)},
{188, (int)(1.33 *100), (int)(1.00*64)},
{188, (int)(1.39 *100), (int)(1.00*64)},
{188, (int)(1.45 *100), (int)(1.00*64)},
{188, (int)(1.52 *100), (int)(1.00*64)},
{188, (int)(1.52 *100), (int)(1.00*64)},
{188, (int)(1.60 *100), (int)(1.00*64)},
{188, (int)(1.68 *100), (int)(1.00*64)},
{188, (int)(1.68 *100), (int)(1.00*64)},
{188, (int)(1.78 *100), (int)(1.00*64)},
{188, (int)(1.88 *100), (int)(1.00*64)},
{188, (int)(1.94 *100), (int)(1.00*64)},
{376, (int)(1.00 *100), (int)(1.00*64)},
{376, (int)(1.03 *100), (int)(1.00*64)},
{376, (int)(1.07 *100), (int)(1.00*64)},
{376, (int)(1.10 *100), (int)(1.00*64)},
{376, (int)(1.14 *100), (int)(1.00*64)},
{376, (int)(1.19 *100), (int)(1.00*64)},
{376, (int)(1.23 *100), (int)(1.00*64)},
{376, (int)(1.28 *100), (int)(1.00*64)},
{376, (int)(1.33 *100), (int)(1.00*64)},
{376, (int)(1.33 *100), (int)(1.00*64)},
{376, (int)(1.39 *100), (int)(1.00*64)},
{376, (int)(1.45 *100), (int)(1.00*64)},
{376, (int)(1.52 *100), (int)(1.00*64)},
{376, (int)(1.52 *100), (int)(1.00*64)},
{376, (int)(1.60 *100), (int)(1.00*64)},
{376, (int)(1.68 *100), (int)(1.00*64)},
{376, (int)(1.68 *100), (int)(1.00*64)},
{376, (int)(1.78 *100), (int)(1.00*64)},
{376, (int)(1.88 *100), (int)(1.00*64)},
{376, (int)(1.94 *100), (int)(1.00*64)},
{564, (int)(1.33 *100), (int)(1.00*64)},
{564, (int)(1.39 *100), (int)(1.00*64)},
{564, (int)(1.45 *100), (int)(1.00*64)},
{564, (int)(1.52 *100), (int)(1.00*64)},
{564, (int)(1.52 *100), (int)(1.00*64)},
{564, (int)(1.60 *100), (int)(1.00*64)},
{564, (int)(1.68 *100), (int)(1.00*64)},
{564, (int)(1.68 *100), (int)(1.00*64)},
{564, (int)(1.78 *100), (int)(1.00*64)},
{564, (int)(1.88 *100), (int)(1.00*64)},
{564, (int)(1.94 *100), (int)(1.00*64)},
{752, (int)(1.50 *100), (int)(1.00*64)},
{752, (int)(1.63 *100), (int)(1.00*64)},
{752, (int)(1.75 *100), (int)(1.00*64)},
{752, (int)(1.88 *100), (int)(1.00*64)},
{752, (int)(1.88 *100), (int)(1.00*64)},
{752, (int)(2.00 *100), (int)(1.00*64)},
{752, (int)(2.13 *100), (int)(1.00*64)},
{752, (int)(2.25 *100), (int)(1.00*64)},
{752, (int)(2.38 *100), (int)(1.00*64)},
{752, (int)(2.50 *100), (int)(1.00*64)},
{752, (int)(2.63 *100), (int)(1.00*64)},
{752, (int)(2.75 *100), (int)(1.00*64)},
{752, (int)(2.88 *100), (int)(1.00*64)},
{752, (int)(2.93 *100), (int)(1.00*64)},
{752, (int)(3.03 *100), (int)(1.00*64)},
{752, (int)(3.14 *100), (int)(1.00*64)},
{752, (int)(3.25 *100), (int)(1.00*64)},
{752, (int)(3.36 *100), (int)(1.00*64)},
{752, (int)(3.48 *100), (int)(1.00*64)},
{752, (int)(3.61 *100), (int)(1.00*64)},
{752, (int)(3.73 *100), (int)(1.00*64)},
{752, (int)(3.86 *100), (int)(1.00*64)},
{752, (int)(4.00 *100), (int)(1.00*64)},
{752, (int)(4.14 *100), (int)(1.00*64)},
{752, (int)(4.29 *100), (int)(1.00*64)},
{752, (int)(4.44 *100), (int)(1.00*64)},
{752, (int)(4.59 *100), (int)(1.00*64)},
{752, (int)(4.76 *100), (int)(1.00*64)},
{752, (int)(4.92 *100), (int)(1.00*64)},
{752, (int)(5.10 *100), (int)(1.00*64)},
{752, (int)(5.28 *100), (int)(1.00*64)},
{752, (int)(5.46 *100), (int)(1.00*64)},
{752, (int)(5.66 *100), (int)(1.00*64)},
{752, (int)(5.86 *100), (int)(1.00*64)},
{752, (int)(6.06 *100), (int)(1.00*64)},
{752, (int)(6.28 *100), (int)(1.00*64)},
{752, (int)(6.50 *100), (int)(1.00*64)},
{752, (int)(6.73 *100), (int)(1.00*64)},
{752, (int)(6.96 *100), (int)(1.00*64)},
{752, (int)(7.21 *100), (int)(1.00*64)},
{752, (int)(7.46 *100), (int)(1.00*64)},
{752, (int)(7.73 *100), (int)(1.00*64)},
{752, (int)(8.00 *100), (int)(1.00*64)},
{752, (int)(8.28 *100), (int)(1.00*64)},
{752, (int)(8.57 *100), (int)(1.00*64)},
{752, (int)(8.88 *100), (int)(1.00*64)},
{752, (int)(9.19 *100), (int)(1.00*64)},
{752, (int)(9.51 *100), (int)(1.00*64)},
{752, (int)(9.85 *100), (int)(1.00*64)},
{752, (int)(10.20*100), (int)(1.00*64)},
{752, (int)(10.56*100), (int)(1.00*64)},
{752, (int)(10.93*100), (int)(1.00*64)},
{752, (int)(11.31*100), (int)(1.00*64)},
{752, (int)(11.71*100), (int)(1.00*64)},
{752, (int)(12.13*100), (int)(1.00*64)},
{752, (int)(12.55*100), (int)(1.00*64)},
{752, (int)(13.00*100), (int)(1.00*64)},
{752, (int)(13.45*100), (int)(1.00*64)},
{752, (int)(13.93*100), (int)(1.00*64)},
{752, (int)(14.42*100), (int)(1.00*64)},
{752, (int)(14.93*100), (int)(1.00*64)},
{752, (int)(15.45*100), (int)(1.00*64)},
{752, (int)(16.00*100), (int)(1.00*64)},
{752, (int)(16.56*100), (int)(1.00*64)},
{752, (int)(17.15*100), (int)(1.00*64)},
{752, (int)(17.75*100), (int)(1.00*64)},
{752, (int)(18.38*100), (int)(1.00*64)},
{752, (int)(19.03*100), (int)(1.00*64)},
{752, (int)(19.70*100), (int)(1.00*64)},
{752, (int)(20.39*100), (int)(1.00*64)},
{752, (int)(21.11*100), (int)(1.00*64)},
{752, (int)(21.86*100), (int)(1.00*64)},
{752, (int)(22.63*100), (int)(1.00*64)},
{752, (int)(23.43*100), (int)(1.00*64)},
{752, (int)(24.25*100), (int)(1.00*64)},
{752, (int)(25.11*100), (int)(1.00*64)},
{752, (int)(25.99*100), (int)(1.00*64)},
{752, (int)(26.91*100), (int)(1.00*64)},
{752, (int)(27.86*100), (int)(1.00*64)},
{752, (int)(28.84*100), (int)(1.00*64)},
{752, (int)(29.86*100), (int)(1.00*64)},
{752, (int)(30.91*100), (int)(1.00*64)},
{752, (int)(32.00*100), (int)(1.00*64)},
{752, (int)(33.13*100), (int)(1.00*64)},

};

////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTION IMPLEMENTATION
////////////////////////////////////////////////////////////////////////////////////////////////////////
static INT32S gc1034_sccb_open(void)
{
	#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_HW
	drv_l1_i2c_init(&gc1034_handle);
	DBG_PRINT("SENSOR_I2C_MODE_HW\r\n");
	#else
	DBG_PRINT("SENSOR_I2C_MODE_SW\r\n");
	#endif

	return STATUS_OK;
}

static void gc1034_sccb_close(void)
{
	#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_HW
	drv_l1_i2c_uninit(&gc1034_handle);
	#endif
}

#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_SW
static INT32S gc1034_sccb_write(INT16U reg, INT8U value)
{
	return drv_l2_sccb_write(&gc1034_handle, reg, value);
	//return drv_l1_reg_1byte_data_1byte_write(&gc1034_handle, reg, value);

}
#endif

#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_SW
static INT32S gc1034_sccb_read(INT16U reg)
{
	INT16U data;
	if(drv_l2_sccb_read(&gc1034_handle, reg, &data) >= 0)
	{
		DBG_PRINT("[SW] R:0x%02x, D:0x%02x\r\n", reg, data);
		return STATUS_OK;
	}
	else
	{
		DBG_PRINT("i2C read fail!\n");
		return STATUS_FAIL;
	}
}
#endif

#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_HW
static INT32S gc1034_sccb_read(INT16U reg, INT8U *value)
{
	if(drv_l1_reg_1byte_data_1byte_read(&gc1034_handle, reg, value) >=0)
	{
		//DBG_PRINT("0x%02x, 0x%02x\r\n", reg, value);
		return STATUS_OK;
	}
	else
	{
		DBG_PRINT("gc1034_sccb_read fail...\r\n");
		return STATUS_FAIL;
	}
}
#endif


static INT32S gc1034_sccb_write_table(regval8_t *pTable)
{
	#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_HW
	INT8U 		Rd_data;
	INT8S 		transmitcnt = 0;
	regval8_t  	*pTable1;
	pTable1 =  	pTable;
	#else
	INT32U retry_cnt = 0;
	#endif

	while(1)
	{
		drv_l1_sys_wdt_clear();
		if(pTable->reg_num == 0xFF && pTable->value == 0xFF)
		{
			break;
		}

		//DBG_PRINT("0x%02x, 0x%02x\r\n", pTable->reg_num, pTable->value);
		#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_SW
		if(gc1034_sccb_write(pTable->reg_num, pTable->value) < 0)
		{
			DBG_PRINT("sccb write fail.\r\n");
			retry_cnt += 1;
			if(retry_cnt >= 10)
				return STATUS_FAIL;
			continue;
		}
		else
		{
			retry_cnt = 0;
		}

		//gc1034_sccb_read(pTable->reg_num);

		if(pTable->reg_num == 0x10 && pTable->value == 0x80)
		{
			OSTimeDly(2);	//wait 20ms
			DBG_PRINT("Delay:20ms\r\n");
		}

		pTable++;
	#else

		if(pTable->reg_num == 0x10 && pTable->value == 0x80)
		{
			OSTimeDly(2);	//wait 20ms
			DBG_PRINT("Delay:20ms\r\n");
		}

		transmitcnt = drv_l1_i2c_group_write(&gc1034_handle,I2C_MISC_2BYTE_REPEAT,(void*)&pTable,1);
		pTable = pTable + transmitcnt;

	#endif

	}
#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_HW
	//if(read_i2c)
	{
		pTable =  pTable1;
		while(1)
		{
			if(pTable->reg_num == 0xFF && pTable->value == 0xFF)
			   break;

			gc1034_sccb_read(pTable->reg_num,&Rd_data);
			DBG_PRINT("addr=0x%x w_data = 0x%x r_data=0x%x \r\n",pTable->reg_num,pTable->value,Rd_data);
			pTable++;
		}
	}
#endif
	return STATUS_OK;
}

#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_SW
static INT32S gc1034_sccb_read_table(regval8_t *pTable)
{
	while(1) {
		if(pTable->reg_num == 0x00 && pTable->value == 0x00) {
			break;
		}

		if(gc1034_sccb_read(pTable->reg_num) < 0) {
			DBG_PRINT("sccb read fail.\r\n");
			continue;
		}
		pTable++;
	}
	DBG_PRINT("\r\n\r\n");

	return STATUS_OK;
}
#endif
/*****************************************************************************************
+++++++++++++++++AEC/AGC
*****************************************************************************************/

static int gc1034_cvt_agc_gain(int analog_gain)
{
	INT32U Analog_Multiple[11]={1000, 1420, 1990, 2850, 4030,5770,8060,11530,16120,23300,32750};

	INT32U Analog_Index;
	INT32U Digital_Gain;
	INT32U Decimal;
	INT32S ret = 0;

	#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_HW
	INT8S transmitcnt;
	regval8_t gc1034_ae_table[8];
	regval8_t *aetable;
  	aetable = (regval8_t*)&gc1034_ae_table;
	#endif

	gc1034_analog_gain = analog_gain*10;
	Analog_Index=0;

	while(Analog_Index<11)
	{
	  if(gc1034_analog_gain<Analog_Multiple[Analog_Index])
	  {
		break;
	  }
	  else
	  {
		Analog_Index++;
	  }
	}

	Digital_Gain = gc1034_analog_gain*1000/Analog_Multiple[Analog_Index-1];
	Decimal=(Digital_Gain*64)/1000;

#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_SW
    ret = gc1034_sccb_write(0xfe, 0x01);
	if(ret < 0)
		return ret;
  	ret = gc1034_sccb_write(0xb1, Decimal >> 6);
	if(ret < 0)
		return ret;
	ret = gc1034_sccb_write(0xb2, (Decimal << 2) & 0xfc);
	if(ret < 0)
		return ret;
	ret = gc1034_sccb_write(0xb6, Analog_Index - 1);
	if(ret < 0)
		return ret;
	ret = gc1034_sccb_write(0xfe, 0x00);
	if(ret < 0)
		return ret;

#elif SENSOR_I2C_MODE == SENSOR_I2C_MODE_HW //-----Hw i2c group write
	gc1034_ae_table[0].reg_num = 0xfe;
	gc1034_ae_table[0].value = 0x01;
	gc1034_ae_table[1].reg_num = 0xb1;
	gc1034_ae_table[1].value = (Decimal >> 6);
	gc1034_ae_table[2].reg_num = 0xb2;
	gc1034_ae_table[2].value = ((Decimal << 2) & 0xfc);
	gc1034_ae_table[3].reg_num = 0xb6;
	gc1034_ae_table[3].value = (Analog_Index - 1);
	gc1034_ae_table[4].reg_num = 0xfe;
	gc1034_ae_table[4].value = 0x00;
	//end
	gc1034_ae_table[5].reg_num = 0xFF;
	gc1034_ae_table[5].value = 0xFF;

	DBG_PRINT(" >");
	transmitcnt = drv_l1_i2c_group_write(&gc1034_handle,I2C_MISC_2BYTE_REPEAT,(void*)&aetable,1);

	if(read_i2c)
	{
		INT8U Rd_data;
		aetable = (regval8_t*)&gc1034_ae_table;

		while(1)
		{
			if(aetable->reg_num == 0xFF && aetable->value == 0xFF)
			   break;

			gc1034_sccb_read(aetable->reg_num,&Rd_data);
			DBG_PRINT("addr=0x%x w_data = 0x%x r_data=0x%x \r\n",aetable->reg_num,aetable->value,Rd_data);
			aetable++;
		}
	}
#endif
	return ret;
}

static int gc1034_set_xfps_exposure_time(sensor_exposure_t *si)
{
	INT8U	t1, t2;
	INT32U	idx, temp;
	INT8S	ret, iso_x = 1;

	#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_HW
	INT8S	transmitcnt;
	regval8_t gc1034_ae_table[8];
	regval8_t *aetable;
	aetable = (regval8_t*)&gc1034_ae_table;
	#endif

	//DBG_PRINT("%s:%d\n", __FUNCTION__, __LINE__);
	/*get iso val*/
	iso_x = (drv_l2_CdspGetIso() & 0xF);
	if(iso_x <= 0)
		iso_x = 1;

	si->sensor_ev_idx += si->ae_ev_step;
	if(si->sensor_ev_idx >= si->max_ev_idx)
		si->sensor_ev_idx = si->max_ev_idx;
	if(si->sensor_ev_idx < 0)
		si->sensor_ev_idx = 0;
	#if C_SENSOR_SAVE_RAW_DATA
	//idx = ((INT32S) g_raw_mode_idx < 0) ? si->sensor_ev_idx * 3 : g_raw_mode_idx * 3;
	//DBG_PRINT("%s:%d %d\n", __FUNCTION__, __LINE__, g_raw_mode_idx);
	idx = g_raw_mode_idx * 3;
	#else
	idx = si->sensor_ev_idx * 3;
	#endif
	si->time = p_expTime_table[idx];
	si->analog_gain = p_expTime_table[idx + 1];
	si->digital_gain = p_expTime_table[idx+2];
	//iso set
	si->analog_gain = (si->analog_gain * iso_x);

#if 0	//ae debug
	DBG_PRINT("[EV=%d, offset=%d]: time = %d, analog gain =0x%x\r\n", si->sensor_ev_idx, si->ae_ev_step, si->time, si->analog_gain);
#endif

	#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_SW
	// exposure time
	if(si->time != pre_sensor_time)
	{
		pre_sensor_time = si->time;
		temp = si->time;

		t1 = (temp & 0xff);
		t2 = (temp >> 8) & 0x00ff;

		ret = gc1034_sccb_write(0x04, t1);
		if(ret < 0)
			return ret;
		ret = gc1034_sccb_write(0x03, t2);
		if(ret < 0)
		{
			DBG_PRINT("ERR: write sensor time = 0x%x!!!\r\n", temp);
			return ret;
		}
	}

	//gain
	if(si->analog_gain != pre_sensor_a_gain)
	{
		// gain
		pre_sensor_a_gain = si->analog_gain;

		temp = si->analog_gain;
		ret = gc1034_cvt_agc_gain(temp);
		if(ret < 0)
		{
			DBG_PRINT("ERR: write sensor analog agin = 0x%x!!!\r\n", temp);
			return ret;
		}
	}
	#elif SENSOR_I2C_MODE == SENSOR_I2C_MODE_HW //-----Hw i2c group write
	// exposure time

	{
		pre_sensor_time = si->time;
		temp = si->time;

		t1 = (temp & 0xff);
		t2 = (temp >> 8) & 0x00ff;

		gc1034_ae_table[0].reg_num = 0x04;
		gc1034_ae_table[0].value = t1;
		gc1034_ae_table[1].reg_num = 0x03;
		gc1034_ae_table[1].value = t2;
		//end
		gc1034_ae_table[2].reg_num = 0xFF;
		gc1034_ae_table[2].value = 0xFF;

		//DBG_PRINT(" >");
		transmitcnt = drv_l1_i2c_group_write(&gc1034_handle,I2C_MISC_2BYTE_REPEAT,(void*)&aetable,1);

		if(read_i2c)
		{
			INT8U Rd_data;
			aetable = (regval8_t*)&gc1034_ae_table;

			while(1) {
				if(aetable->reg_num == 0xFF && aetable->value == 0xFF)
				   break;

				gc1034_sccb_read(aetable->reg_num,&Rd_data);
				DBG_PRINT("addr=0x%x w_data = 0x%x r_data=0x%x \r\n",aetable->reg_num,aetable->value,Rd_data);
				aetable++;
			}
		}

	}
	//gain
	{
		pre_sensor_a_gain = si->analog_gain;

		temp = si->analog_gain;
		ret = gc1034_cvt_agc_gain(temp);
		if(ret < 0)
		{
			DBG_PRINT("ERR: write sensor analog agin = 0x%x!!!\r\n", temp);
			return ret;
		}
	}
	#endif

	return 0;
}


static void gc1034_set_ae(int ev_step)
{
	seInfo.ae_ev_step = ev_step;
	gc1034_set_xfps_exposure_time(&seInfo);
}

void sensor_register_ae_ctrl(INT32U *handle)
{
	*handle = (INT32U) gc1034_set_ae;
}

void sensor_get_ae_info(sensor_exposure_t *si)
{
	gp_memcpy((INT8S*)si, (INT8S*)&seInfo, sizeof(sensor_exposure_t));
}

void sensor_set_max_lum(int max_lum)
{
	seInfo.max_ev_idx = seInfo.total_ev_idx - (128 - max_lum);
	DBG_PRINT("MaxLum:%d, MaxEvIdx:%d, TotalEvIdx:%d\r\n",max_lum, seInfo.max_ev_idx, seInfo.total_ev_idx);
}


/*****************************************************************************************
-------------------AEC/AGC
*****************************************************************************************/

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
void gc1034_mipi_set_exp_freq(INT8U freq)
{
	if(freq == 50)
	{
		seInfo.sensor_ev_idx = GC1034_25FPS_50HZ_INIT_EV_IDX;
		seInfo.ae_ev_step = 0;
		seInfo.daylight_ev_idx = GC1034_25FPS_50HZ_DAY_EV_IDX;
		seInfo.night_ev_idx = GC1034_25FPS_50HZ_NIGHT_EV_IDX;
		seInfo.max_ev_idx = GC1034_25FPS_50HZ_MAX_EV_IDX;
		seInfo.total_ev_idx = GC1034_25FPS_50HZ_EXP_TIME_TOTAL;

		p_expTime_table = (int *) GC1034_mipi_25fps_exp_time_gain_50Hz;
		DBG_PRINT(">>Set frequence 50Hz.\r\n");
	}
	else
	if(freq == 60)
	{
		seInfo.sensor_ev_idx = GC1034_25FPS_60HZ_INIT_EV_IDX;
		seInfo.ae_ev_step = 0;
		seInfo.daylight_ev_idx = GC1034_25FPS_60HZ_DAY_EV_IDX;
		seInfo.night_ev_idx = GC1034_25FPS_60HZ_NIGHT_EV_IDX;
		seInfo.max_ev_idx = GC1034_25FPS_60HZ_MAX_EV_IDX;
		seInfo.total_ev_idx = GC1034_25FPS_60HZ_EXP_TIME_TOTAL;

		p_expTime_table = (int *) GC1034_mipi_25fps_exp_time_gain_60Hz;

		DBG_PRINT(">>Set frequence 60Hz.\r\n");
	}
	sensor_set_max_lum(g_FavTable.max_lum);
}

void gc1034_mipi_seinfo_init(void)
{
	seInfo.sensor_ev_idx = GC1034_25FPS_50HZ_INIT_EV_IDX;
	seInfo.ae_ev_step = 0;
	seInfo.daylight_ev_idx = GC1034_25FPS_50HZ_DAY_EV_IDX;
	seInfo.night_ev_idx = GC1034_25FPS_50HZ_NIGHT_EV_IDX;
	seInfo.max_ev_idx = GC1034_25FPS_50HZ_MAX_EV_IDX;
	seInfo.total_ev_idx = GC1034_25FPS_50HZ_EXP_TIME_TOTAL;

	p_expTime_table = (int *) GC1034_mipi_25fps_exp_time_gain_50Hz;

	pre_sensor_time = 1;
	pre_sensor_a_gain = 0x00;

	seInfo.time = 1;
	seInfo.analog_gain = 0x00;
	seInfo.digital_gain = 0x40;
}



#if MIPI_ISR_TEST
static void mipi_gc1034_handle(INT32U dev_no, INT32U event)
{
	if(event & MIPI_LANE0_SOT_SYNC_ERR)
	{
		DBG_PRINT("LANE0_SOT_SYNC_ERR\r\n");
	}

	if(event & MIPI_HD_1BIT_ERR)
	{
		DBG_PRINT("HD_1BIT_ERR\r\n");
	}

	if(event & MIPI_HD_NBIT_ERR)
	{
		DBG_PRINT("HD_NBIT_ERR\r\n");
	}

	if(event & MIPI_DATA_CRC_ERR)
	{
		DBG_PRINT("DATA_CRC_ERR\r\n");
	}

	if(event & MIPI_LANE1_SOT_SYNC_ERR)
	{
		DBG_PRINT("LANE1_SOT_SYNC_ERR\r\n");
	}

	if(event & MIPI_CCIR_SOF)
	{
		DBG_PRINT("CCIR_SOF\r\n");
	}
}

#endif

static void gc1034_mipi_sensor_init(void)
{

	// reguest sccb
	gc1034_sccb_open();

	// reset sensor
	gc1034_sccb_write_table((regval8_t *) gc1034_reset_table);


	OSTimeDly(20);

	// init sensor
	gc1034_sccb_write_table((regval8_t *) gc1034_init_table);

	#if SENSOR_I2C_MODE == SENSOR_I2C_MODE_SW
	gc1034_sccb_read_table((regval8_t *)gc1034_init_table);
	#endif

	DBG_PRINT("Sensor GC1034 mipi init completed\r\n");
}

/**
 * @brief   initialization function
 * @param   sensor format parameters
 * @return 	none
 */


void gc1034_cdsp_mipi_init(void)
{
	DBG_PRINT("%s\r\n", __func__);

	//ae init
	gc1034_mipi_seinfo_init();	/*ae init*/
	//cdsp init
	drv_l2_cdsp_open();			/*cdsp init*/

	// Reset
#ifdef FRONT_SENSOR_RESET		/*reset sensor*/
	gpio_set_port_attribute(FRONT_SENSOR_RESET, ATTRIBUTE_HIGH);
	gpio_init_io(FRONT_SENSOR_RESET, GPIO_OUTPUT);
	gpio_write_io(FRONT_SENSOR_RESET, DATA_HIGH);

	OSTimeDly(5);
	gpio_write_io(FRONT_SENSOR_RESET, DATA_LOW);

	OSTimeDly(10);
	gpio_write_io(FRONT_SENSOR_RESET, DATA_HIGH);

	OSTimeDly(10);
#endif

	// mipi enable
#if (MIPI_DEV_NO == 1)
	drv_l1_mipi_init(MIPI_1, ENABLE);
#else
	drv_l1_mipi_init(MIPI_0, ENABLE);
#endif
	DBG_PRINT("Sensor GC1034 cdsp mipi[%d] init completed\r\n", MIPI_DEV_NO);
}

/**
 * @brief   un-initialization function
 * @param   sensor format parameters
 * @return 	none
 */
static void gc1034_cdsp_mipi_uninit(void)
{
	DBG_PRINT("%s\r\n", __func__);

	// disable mclk
	drv_l2_sensor_set_mclkout(MCLK_NONE, MASTER_CLOCK_MIPI_OFF, MASTER_CLOCK_CSI_OFF);

	// cdsp disable
	drv_l2_cdsp_close();
	// mipi disable
#if (MIPI_DEV_NO == 1)
	drv_l1_mipi_init(MIPI_1, DISABLE);
#else
	drv_l1_mipi_init(MIPI_0, DISABLE);
#endif

	// release sccb
	gc1034_sccb_close();
}

/**
 * @brief   stream start function
 * @param   info index
 *
 * @return 	none
 */
void gc1034_cdsp_mipi_stream_on(INT32U index, INT32U bufA, INT32U bufB)
{
	INT16U		target_w, target_h, sensor_w, sensor_h;
	gpCdspFmt_t format;

	// set sensor size
	DBG_PRINT("%s = %d\r\n", __func__, index);

	/*Enable Mclk out*/
	//drv_l2_sensor_set_mclkout(gc1034_cdsp_mipi_ops.info[index].mclk, MASTER_CLOCK_MIPI_ON, MASTER_CLOCK_CSI_KEEP);
	drv_l1_csi_set_clock(gc1034_cdsp_mipi_ops.info[index].mclk, MASTER_CLOCK_MIPI_ON, MASTER_CLOCK_CSI_KEEP);

	//Enabel mipi clk, set mipi clk
	#if 0
	//drv_l2_mipi_ctrl_set_clk(ENABLE, 4);	//for GENERATE_PIXEL_CLK
	OSTimeDly(3);						//wait 3ms
	#endif

	/* cdsp clock */
#if MIPI_DEV_NO == 1
	drv_l1_CdspSetClockTree(ENABLE, MIPI1_INPUT, RAW);
#else
	drv_l1_CdspSetClockTree(ENABLE, MIPI_INPUT, RAW);
#endif

    // set cdsp format
#if MIPI_DEV_NO == 0
	format.image_source = C_CDSP_MIPI;
#else
	format.image_source = C_CDSP_MIPI1;
#endif
	format.input_format = gc1034_cdsp_mipi_ops.info[index].input_format;
	format.output_format = gc1034_cdsp_mipi_ops.info[index].output_format;
	target_w = gc1034_cdsp_mipi_ops.info[index].target_w;
	target_h = gc1034_cdsp_mipi_ops.info[index].target_h;
	format.hpixel = sensor_w = gc1034_cdsp_mipi_ops.info[index].sensor_w;
	format.vline = sensor_h = gc1034_cdsp_mipi_ops.info[index].sensor_h;
	format.hoffset =gc1034_cdsp_mipi_ops.info[index].hoffset;
	format.voffset = gc1034_cdsp_mipi_ops.info[index].voffset;
	format.sensor_timing_mode = gc1034_cdsp_mipi_ops.info[index].interface_mode;
	format.sensor_hsync_mode = gc1034_cdsp_mipi_ops.info[index].hsync_active;
	format.sensor_vsync_mode = gc1034_cdsp_mipi_ops.info[index].vsync_active;

	if(drv_l2_cdsp_set_fmt(&format) < 0)
	{
		DBG_PRINT("cdsp set fmt err!!!\r\n");
	}
	// set scale down
	/*
	if((format.hpixel > target_w) || (format.vline > target_h))
	{
		drv_l2_cdsp_set_yuv_scale(target_w, target_h);
	}
   */
	// cdsp start
	drv_l2_CdspTableRegister((gpCisCali_t *) &g_cali);
	drv_l2_cdsp_stream_on(AEAWB_TASK_ONOFF, bufA, bufB);		//Disable AE,AWB,SetSensor Task
	//drv_l2_cdsp_stream_on(DISABLE, bufA, bufB);
	drv_l1_CdspSetDataSource(C_CDSP_SDRAM);
	drv_l2_cdsp_enable((gpUserFav_t*)&g_FavTable ,sensor_w, sensor_h, target_w, target_h);
	drv_l2_cdsp_sat_contrast_reinit_thr();

	// set mipi format.
/*
	switch(index)
	{
	case 0:
	case 1:
	case 2:
	case 3:
		gc1034_mipi_cfg.data_from_mmr = MIPI_AUTO_DETECT;
		gc1034_mipi_cfg.data_type = MIPI_RAW10;
		break;

	default:
		gc1034_mipi_cfg.data_from_mmr = MIPI_AUTO_DETECT;
		gc1034_mipi_cfg.data_type = MIPI_RAW10;
	}
*/
	//mipi start
#if (MIPI_DEV_NO == 1)
	if(drv_l1_mipi_set_parameter(MIPI_1, &gc1034_mipi_cfg) < 0)
	{
		DBG_PRINT("MIPI1 init fail !!!\r\n");
	}

		#if MIPI_ISR_TEST
		vic_irq_enable(VIC_MIPI_B);
		drv_l1_mipi_isr_register(mipi_gc1034_handle);
		drv_l1_mipi_set_irq_enable(MIPI_1, ENABLE, MIPI_INT_ALL);
		#endif
#else
	if(drv_l1_mipi_set_parameter(MIPI_0, &gc1034_mipi_cfg) < 0)
	{
		DBG_PRINT("MIPI0 init fail !!!\r\n");
	}
	else
	{
		//DBG_PRINT("MIPI0 init completed.\r\n");
		#if MIPI_ISR_TEST
		vic_irq_enable(VIC_MIPI);
		drv_l1_mipi_isr_register(mipi_gc1034_handle);
		drv_l1_mipi_set_irq_enable(MIPI_0, ENABLE, MIPI_INT_ALL);
		#endif
	}

#endif

	/*Init Sensor*/
	gc1034_mipi_sensor_init();

	// reset sensor ev idx
	seInfo.ae_ev_step = 0;
	gc1034_set_xfps_exposure_time(&seInfo);
	DBG_PRINT("GC1034 mipi Exposure Time set!!\r\n");

	drv_l1_CdspSetDataSource(C_CDSP_MIPI);
	DBG_PRINT("GC1034 cdsp mipi init done!!\r\n");

}

/**
 * @brief   stream stop function
 * @param   none
 * @return 	none
 */
static void gc1034_cdsp_mipi_stream_off(void)
{
	//drv_l2_cdsp_stream_off();
}

/**
 * @brief   get info function
 * @param   none
 * @return 	pointer to sensor information data
 */
static drv_l2_sensor_info_t *gc1034_cdsp_mipi_get_info(INT32U index)
{
	if(index > (MAX_INFO_NUM - 1))
	{
		return NULL;
	}
	else
	{
		return (drv_l2_sensor_info_t *) &gc1034_cdsp_mipi_ops.info[index];
	}
}

/*********************************************
*	sensor ops declaration
*********************************************/
const drv_l2_sensor_ops_t gc1034_cdsp_mipi_ops =
{
	SENSOR_SOURCE_MIPI,
	SENSOR_PATH_CDSP,
	gc1034_cdsp_mipi_init,
	gc1034_cdsp_mipi_uninit,
	gc1034_cdsp_mipi_stream_on,
	gc1034_cdsp_mipi_stream_off,
	NULL,
	NULL,
	gc1034_mipi_set_exp_freq,
	gc1034_cdsp_mipi_get_info,
	{
		/* 1st info */
		{
			MASTER_CLOCK_24MHZ,		/* MCLK */
			V4L2_PIX_FMT_SBGGR10,	/* input format */
			V4L2_PIX_FMT_YUYV,		/* output format */
			25,						/* FPS in sensor */
			GC1034_OUT_WIDTH,		/* target width */
			GC1034_OUT_HEIGHT,		/* target height */
			GC1034_WIDTH,			/* sensor width */
			GC1034_HEIGHT,			/* sensor height */

			#if SENSOR_FLIP
			3,						/* sensor h offset */
			0,						/* sensor v offset */
			#else
			4,						/* sensor h offset */
			0,						/* sensor v offset */
			#endif

			MODE_CCIR_601,			/* input interface */
			MODE_NONE_INTERLACE,	/* interlace mode */
			MODE_ACTIVE_HIGH,		/* hsync pin active level */
			MODE_ACTIVE_HIGH,		/* vsync pin active level */
		}
	}
};
#endif //(defined _SENSOR_GC1034_CDSP_MIPI) && (_SENSOR_GC1034_CDSP_MIPI == 1)
